home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Tools / Win95 Secrets / SETUP.Z / VAR2MAP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-19  |  6.8 KB  |  255 lines

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <malloc.h>
  6. #include <direct.h>
  7.  
  8. typedef struct
  9. {
  10.     unsigned address;
  11.     char * pszName;
  12. } _32BIT_SYMBOL, * P32BIT_SYMBOL;
  13.  
  14. char SzInputVarFile[ MAX_PATH ];
  15. char SzExeFile[ MAX_PATH ];
  16. char SzMapFile[ MAX_PATH ];
  17.  
  18. #define SYMBOL_REALLOC_SIZE 100
  19.  
  20. unsigned CSymbols = 0;
  21. P32BIT_SYMBOL P32BitSymbols = 0;
  22.  
  23. int _32BitSymbolSort( const void *a, const void *b )
  24. {
  25.     return (int) (((P32BIT_SYMBOL)a)->address - ((P32BIT_SYMBOL)b)->address);
  26. }
  27.  
  28. // When called, the .VAR file should be positioned to the start of the symbols
  29. BOOL ReadAndSort32BitSymbols( FILE *varFile )
  30. {
  31.     char szInputBuffer[512];
  32.     char szSymbolName[256];
  33.     unsigned symAddress;
  34.  
  35.     while ( !feof(varFile) && fgets(szInputBuffer, sizeof(szInputBuffer), varFile) )
  36.     {
  37.         if ( sscanf( szInputBuffer, "%s = %x", szSymbolName, &symAddress) != 2 )
  38.         {
  39.             printf( "unhandled line: %s\n", szInputBuffer );
  40.             continue;
  41.         }
  42.         
  43.         if ( (CSymbols % SYMBOL_REALLOC_SIZE) == 0 )
  44.         {
  45.             P32BitSymbols = realloc( P32BitSymbols,
  46.                                     (CSymbols + SYMBOL_REALLOC_SIZE) * sizeof(_32BIT_SYMBOL) );
  47.             if ( !P32BitSymbols )
  48.             {
  49.                 printf("unable to allocate memory for 32 bit symbols\n");
  50.                 return FALSE;
  51.             }
  52.         }
  53.         
  54.         P32BitSymbols[ CSymbols ].address = symAddress;
  55.         P32BitSymbols[ CSymbols ].pszName = strdup( szSymbolName );
  56.         if ( !P32BitSymbols[ CSymbols ].pszName )
  57.         {
  58.             printf("unable to allocate memory for 32 bit symbol names\n");
  59.             return FALSE;
  60.         }
  61.         CSymbols++;
  62.     }
  63.     
  64.     qsort( P32BitSymbols, CSymbols, sizeof(_32BIT_SYMBOL), _32BitSymbolSort );
  65.     
  66.     return TRUE;
  67. }
  68.  
  69. BOOL ProcessVarFile( void )
  70. {
  71.     FILE * varFile = 0, *exeFile = 0, *mapFile = 0;
  72.     char szInputBuffer[512];
  73.     char szAnotherBuffer[256];
  74.     BOOL _32BitFile = FALSE;
  75.     IMAGE_DOS_HEADER dosHeader;
  76.     IMAGE_NT_HEADERS ntHeaders;
  77.     PIMAGE_SECTION_HEADER pSections = 0;
  78.     unsigned i, sectionNumber, currentSectionBase, nextSectionBase;
  79.     PSTR p;
  80.     
  81.     __try
  82.     {
  83.  
  84.     varFile = fopen( SzInputVarFile, "rt" );
  85.     
  86.     if ( !varFile )
  87.     {
  88.         printf( "Unable to open %s\n", SzInputVarFile );
  89.         return FALSE;
  90.     }
  91.     
  92.     if ( !fgets(szInputBuffer, sizeof(szInputBuffer), varFile) )
  93.     {
  94.         printf( "Unable to read first line of input file (FILE=)\n");
  95.         return FALSE;
  96.     }
  97.     
  98.     if ( sscanf(szInputBuffer, "FILE = %s", SzExeFile) != 1 )
  99.     {
  100.         printf( "FILE = line not found\n" );
  101.         return FALSE;
  102.     }
  103.  
  104.     _32BitFile = TRUE;
  105.  
  106.     exeFile = fopen( SzExeFile, "rb" );
  107.     if ( !exeFile )
  108.     {
  109.         printf( "unable to open %s\n", SzExeFile );
  110.         return FALSE;
  111.     }
  112.  
  113.     if ( !fread( &dosHeader, sizeof(dosHeader), 1, exeFile) )
  114.     {
  115.         printf( "unable to read DOS header of %s\n", SzExeFile );
  116.         return FALSE;
  117.     }
  118.     
  119.     if ( dosHeader.e_magic != IMAGE_DOS_SIGNATURE )
  120.     {
  121.         printf( "MZ header not found in %s\n", SzExeFile );
  122.         return FALSE;
  123.     }
  124.  
  125.     ntHeaders.Signature = 0;
  126.     fseek(exeFile, dosHeader.e_lfanew, SEEK_SET);
  127.     fread( &ntHeaders, sizeof(ntHeaders), 1, exeFile );
  128.     if ( ntHeaders.Signature != IMAGE_NT_SIGNATURE )
  129.     {
  130.         printf( "%s is not a valid Win32 PE file\n", SzExeFile );
  131.         return FALSE;
  132.     }
  133.  
  134.     pSections = malloc( ntHeaders.FileHeader.NumberOfSections * IMAGE_SIZEOF_SECTION_HEADER );
  135.     if ( !pSections )
  136.     {
  137.         printf( "unable to allocate memory for sections\n" );
  138.         return FALSE;       
  139.     }
  140.  
  141.     if ( !fread(pSections, ntHeaders.FileHeader.NumberOfSections,
  142.                 IMAGE_SIZEOF_SECTION_HEADER, exeFile) )
  143.     {
  144.         printf( "unable to read sections\n" );
  145.         return FALSE;               
  146.     }
  147.     
  148.     strcpy( SzMapFile, SzExeFile );
  149.     p = strrchr(SzMapFile, '.');
  150.     if ( p )
  151.         strcpy( p+1, "MAP" );
  152.     else
  153.         strcat( SzMapFile, ".MAP");
  154.  
  155.     mapFile = fopen( SzMapFile, "wt" );
  156.     if ( !exeFile )
  157.     {
  158.         printf( "unable to open %s\n", SzMapFile );
  159.         return FALSE;
  160.     }
  161.  
  162.     if ( !ReadAndSort32BitSymbols( varFile ) )
  163.         return FALSE;
  164.  
  165.     fprintf( mapFile, " Start         Length     Name                   Class\n" );
  166.  
  167.     for ( i = 0; i < ntHeaders.FileHeader.NumberOfSections; i++ )
  168.     {
  169.         fprintf( mapFile,
  170.                 " %04X:00000000 0%08X %-23.8s %s 32-bit\n",
  171.                 i+1,
  172.                 pSections[i].Misc.VirtualSize, 
  173.                 pSections[i].Name,
  174.                 pSections[i].Characteristics & IMAGE_SCN_MEM_EXECUTE ? "CODE" : "DATA" );
  175.     }
  176.  
  177.     fprintf(mapFile, "\n  Address         Publics by Value\n\n");
  178.  
  179.     sectionNumber = 1;
  180.     
  181.     for ( i = 0; i < CSymbols; i++ )
  182.     {
  183. calculateSection:
  184.         if ( sectionNumber > ntHeaders.FileHeader.NumberOfSections )
  185.         {
  186.             printf("%s is above a valid address in this module\n", P32BitSymbols[ i ].pszName);
  187.             break;
  188.         }
  189.  
  190.         currentSectionBase = ntHeaders.OptionalHeader.ImageBase + pSections[sectionNumber-1].VirtualAddress;
  191.         nextSectionBase = currentSectionBase + pSections[sectionNumber-1].Misc.VirtualSize;
  192.  
  193.         if ( P32BitSymbols[ i ].address >= nextSectionBase )
  194.         {
  195.             sectionNumber++;
  196.             goto calculateSection;
  197.         }
  198.             
  199.         if ( currentSectionBase > P32BitSymbols[ i ].address )
  200.             printf("%s is below a valid address in this module\n", P32BitSymbols[ i ].pszName);
  201.         
  202.         fprintf( mapFile, " %04X:%08X       %s\n",
  203.             sectionNumber,
  204.             P32BitSymbols[ i ].address - currentSectionBase,
  205.             P32BitSymbols[ i ].pszName );
  206.         
  207.         free( P32BitSymbols[ i ].pszName );
  208.     }
  209.     
  210.     }   // End of __try block
  211.     __finally
  212.     {
  213.     if ( varFile )
  214.         fclose( varFile );
  215.     
  216.     if ( exeFile )
  217.         fclose( exeFile );
  218.     
  219.     if ( mapFile )
  220.         fclose( mapFile );
  221.     
  222.     if ( P32BitSymbols )
  223.         free( P32BitSymbols );
  224.     }
  225.     
  226.     return TRUE;
  227. }
  228.  
  229. // Returns TRUE if program should continue, FALSE otherwise
  230. BOOL ParseCommandLine(int argc, char *argv[])
  231. {
  232.     if ( argc != 2 )
  233.         return FALSE;
  234.     
  235.     strcpy( SzInputVarFile, argv[1] );
  236.  
  237.     return TRUE;
  238. }
  239.  
  240. int main( int argc, char *argv[] )
  241. {
  242.     printf( "VAR2MAP - Matt Pietrek 1995\n" );
  243.  
  244.     if ( !ParseCommandLine(argc, argv) )
  245.     {
  246.         printf( "Syntax: VAR2MAP filename\n" );
  247.         return 1;
  248.     }
  249.     
  250.     if ( !ProcessVarFile() )
  251.         return 1;
  252.  
  253.     return 0;
  254. }
  255.